package com.gzz.orchid.context.domain.rbac.impl;

import com.gzz.orchid.common.boot.mybatis.conditices.QueryCondition;
import com.gzz.orchid.common.core.authorization.UserContextHolder;
import com.gzz.orchid.context.domain.rbac.IRoleRepository;
import com.gzz.orchid.context.domain.rbac.entity.Permission;
import com.gzz.orchid.context.domain.rbac.entity.RoleDo;
import com.gzz.orchid.context.infrastructure.definition.Action;
import com.gzz.orchid.context.infrastructure.definition.Status;
import com.gzz.orchid.context.infrastructure.persistence.entity.sys.SysPermissionPo;
import com.gzz.orchid.context.infrastructure.persistence.entity.sys.SysRolePo;
import com.gzz.orchid.context.infrastructure.persistence.mapper.sys.SysPermissionMapper;
import com.gzz.orchid.context.infrastructure.persistence.mapper.sys.SysRoleMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author higmd
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class RoleRepository implements IRoleRepository {
    private final SysRoleMapper mapper;
    private final SysPermissionMapper permissionMapper;

    @Override
    public RoleDo findByCode(String code) {
        var condit = new QueryCondition();
        condit.eq("code", code);
        SysRolePo po =mapper.selectOneByCondition(condit);
        return Optional.ofNullable(po).map(RoleDo::convertFrom).orElse(null);
    }

    @Override
    public List<RoleDo> findListByIds(Serializable[] ids) {
        List<SysRolePo> poList = mapper.selectListByIds(ids);
        //
        return poList.stream()
                .map(RoleDo::convertFrom)
                .collect(Collectors.toList());
    }

    @Override
    public int batchDelete(Serializable[] ids) {
        var n = mapper.removeByIds(ids);
        // 记录日志log
        log.info("删除角色[{}]成功，删除{}行数据", ids, n);
        return n;
    }

    @Override
    public int batchChangeStatus(Status status, List<RoleDo> doList) {
        var po = new SysRolePo();
        po.setStatus(status.getValue());
        po.setUpdatedOn(LocalDateTime.now());
        po.setUpdatedBy(UserContextHolder.getUserCode());
        //条件
        QueryCondition condit = new QueryCondition();
        condit.in("id", doList.stream().map(RoleDo::getId).toArray());
        var n = mapper.updateByCondition(po, condit);
        // 记录日志log
        log.info("批量修改[{}]角色状态[{}]成功，影响{}行数据", doList.size(), status.getValue(), n);
        return n;
    }

    @Override
    public void save(RoleDo roleDo) {
        var po = new SysRolePo();
        var n = (roleDo.getId() != null)? mapper.insert(po): mapper.updateById(po);
        // 记录日志log
        log.info("保存角色[{}]成功，影响{}行数据", roleDo.getName(), n);
    }

    @Override
    public List<Permission> getPermissions(String code) {
        var condit = new QueryCondition();
        condit.eq("role_code", code);
        List<SysPermissionPo> poList = permissionMapper.selectListByCondition(condit);
        return poList.stream()
                .map(po -> {
                    var perm = new Permission();
                    perm.setModuleCode(po.getModuleCode());
                    perm.setRoleCode(po.getRoleCode());
                    perm.setActions(Action.parseSet(po.getPurview()));
                    return perm;
                })
                .collect(Collectors.toList());
    }
}
